package org.abettor.util.https;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

import javax.net.ssl.HttpsURLConnection;

/**
 * 完成客户端到服务器的 HTTPS 请求过程，并返回请求结果。
 * @author <a href="http://www.abettor.org/" target="_blank">abettor</a>
 * @deprecated
 */
public class HttpsRequest
{
	private String	strMethod	= "GET";
	private String	strHost		= null;
	private int		nPort		= 443;
	private String	strUrl		= "/";
	private byte []	byteData	= null;

	/**
	 * 构造函数，类的实例化
	 */
	public HttpsRequest()
	{
	}

	/**
	 * 构造函数，类的实例化
	 * @param strHost 服务器的域名或 IP 地址
	 */
	public HttpsRequest(String strHost)
	{
		this.strHost = strHost;
	}

	/**
	 * 构造函数，类的实例化
	 * @param strHost 服务器的域名或 IP 地址
	 * @param strUrl 要请求的目标路径。应以“/”字符开头。
	 */
	public HttpsRequest(String strHost, String strUrl)
	{
		this.strHost = strHost;
		if(strUrl.charAt(0) != '/')
		{
			this.strUrl += strUrl;
		}
		else
		{
			this.strUrl = strUrl;
		}
	}

	/**
	 * 构造函数，类的实例化
	 * @param strHost 服务器的域名或 IP 地址
	 * @param nPort 服务器监听端口
	 * @param strUrl 要请求的目标路径。应以“/”字符开头。
	 */
	public HttpsRequest(String strHost, int nPort, String strUrl)
	{
		this.strHost = strHost;
		this.nPort = nPort;
		if(strUrl.charAt(0) != '/')
		{
			this.strUrl += strUrl;
		}
		else
		{
			this.strUrl = strUrl;
		}
	}

	/**
	 * 构造函数，类的实例化
	 * @param strHost 服务器的域名或 IP 地址
	 * @param nPort 服务器监听端口
	 * @param strUrl 要请求的目标路径。应以“/”字符开头。
	 * @param strMethod HTTP 协议中规定的请求方法，如“GET”、“POST”、“HEAD”等。
	 * @param byteData HTTP 协议包体中要发送的数据
	 */
	public HttpsRequest(String strHost, int nPort, String strUrl, String strMethod, byte [] byteData)
	{
		this.strMethod = strMethod;
		this.strHost = strHost;
		this.nPort = nPort;
		this.byteData = byteData;
		if(strUrl.charAt(0) != '/')
		{
			this.strUrl += strUrl;
		}
		else
		{
			this.strUrl = strUrl;
		}
	}

	/**
	 * 构造函数，类的实例化
	 * @param strHost 服务器的域名或 IP 地址
	 * @param nPort 服务器监听端口
	 * @param strUrl 要请求的目标路径。应以“/”字符开头。
	 * @param strMethod HTTP 协议中规定的请求方法，如“GET”、“POST”、“HEAD”等。
	 * @param strData HTTP 协议包体中要发送的数据
	 */
	public HttpsRequest(String strHost, int nPort, String strUrl, String strMethod, String strData)
	{
		this.strMethod = strMethod;
		this.strHost = strHost;
		this.nPort = nPort;
		this.byteData = strData.getBytes();
		if(strUrl.charAt(0) != '/')
		{
			this.strUrl += strUrl;
		}
		else
		{
			this.strUrl = strUrl;
		}
	}

	/**
	 * 构造函数，类的实例化
	 * @param strHost 服务器的域名或 IP 地址
	 * @param strUrl 要请求的目标路径。应以“/”字符开头。
	 * @param strData HTTP 协议包体中要发送的数据
	 */
	public HttpsRequest(String strHost, String strUrl, String strData)
	{
		this.strMethod = "POST";
		this.strHost = strHost;
		this.byteData = strData.getBytes();
		if(strUrl.charAt(0) != '/')
		{
			this.strUrl += strUrl;
		}
		else
		{
			this.strUrl = strUrl;
		}
	}

	/**
	 * 设置 HTTP 协议包体中要发送的数据
	 * @param byteData HTTP 协议包体中要发送的数据
	 */
	public void setData(byte [] byteData)
	{
		this.byteData = byteData;
	}

	/**
	 * 设置 HTTP 协议包体中要发送的数据
	 * @param strData HTTP 协议包体中要发送的数据
	 */
	public void setData(String strData)
	{
		this.byteData = strData.getBytes();
	}

	/**
	 * 设置服务器监听端口
	 * @param nPort 服务器监听端口
	 */
	public void setPort(int nPort)
	{
		this.nPort = nPort;
	}

	/**
	 * 设置要连接的服务器域名或 IP 地址
	 * @param strHost 服务器域名或 IP 地址
	 */
	public void setHost(String strHost)
	{
		this.strHost = strHost;
	}

	/**
	 * 设置访问服务器的 HTTP 协议方法
	 * @param strMethod HTTP 协议中规定的请求方法，如“GET”、“POST”、“HEAD”等。
	 */
	public void setMethod(String strMethod)
	{
		this.strMethod = strMethod;
	}

	/**
	 * 设置要请求的目标路径
	 * @param strUrl 目标路径。应以“/”字符开头。
	 */
	public void setUrl(String strUrl)
	{
		this.strUrl = strUrl;
	}

	/**
	 * 发送 HTTPS 请求到目的服务器，并获取服务器返回的结果。
	 * @return 返回服务器的响应信息（HTTP 协议包的包体）。失败返回 null。
	 */
	public byte [] getResponseByRequest()
	{
		if(nPort <= 0)
			return null;
		
		if("".equals(strHost))
			return null;
		
		StringBuffer requestUrl = new StringBuffer();
		requestUrl.append("https://");
		requestUrl.append(strHost);
		if(nPort != 443)
			requestUrl.append(":" + nPort);
		requestUrl.append(strUrl);
		
		HttpsURLConnection httpsConn = HttpsConnection.getHttpsConnection(requestUrl.toString());
		if(httpsConn == null)
			return null;
		
		StringBuffer requestString = new StringBuffer();
		requestString.append(strMethod + " " + strUrl + " HTTP/1.1\r\n");
		requestString.append("Host: " + strHost + ":" + nPort + "\r\n");
		requestString.append("Content-Type: text/xml; charset: UTF-8\r\n");
		if(byteData != null)
			requestString.append("Content-Length: " + byteData.length + "\r\n");
		else
			requestString.append("Content-Length: 0\r\n");
		requestString.append("Connection: close\r\n");
		requestString.append("\r\n");
		requestString.append(byteData);
		
		httpsConn.setDoOutput(true);
		httpsConn.setDoInput(true);
		
		OutputStream outputStream = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
		try
		{
			outputStream = httpsConn.getOutputStream();
			if(outputStream == null)
				return null;
			
			//	Send the request
			outputStream.write(requestString.toString().getBytes());
			
			inputStream = httpsConn.getInputStream();
			if(inputStream == null)
				return null;

			inputStreamReader = new InputStreamReader(inputStream);
			StringBuffer strBuf = new StringBuffer();
			char [] chBuf = { '\0' };
			while(inputStreamReader.read(chBuf) != -1)
			{
				strBuf.append(chBuf);
			}
			
			return strBuf.toString().getBytes();
		}
		catch (IOException e)
		{
			e.printStackTrace();
			return null;
		}
	}
}
